package domain.message ;

import java.util.List;
import java.util.Vector;

import org.compass.annotations.Searchable;
import org.compass.annotations.SearchableProperty;

import persistence.Persistent;
import presentation.UIDirectory;

/**
 * The Class Directory. represents a sub-forum each Directory can have children Directory. each Directory has
 * a list of Threads ids
 */
@Searchable
public class Directory extends Persistent implements UIDirectory
{
	private static final long serialVersionUID = -4301221664367663692L ;

	private Vector<Long> children ;


	@SearchableProperty(name = "name")
	private String name ;
	private Vector<Long> threads ;

	/**
	 * constructor-Instantiates a new Directory.
	 * @param id id of this directory.
	 * @param name the name of the Directory
	 */
	public Directory(final long id, final String name)
	{
		this(id, name, new Vector<Long>()) ;
	}

	/**
	 * second constructor-Instantiates a new Directory.
	 * @param id id of this directory.
	 * @param name the name of the Directory
	 * @param children The vector which holds all the children Directory id's of this Directory.
	 */
	public Directory(final long id, final String name, final Vector<Long> children)
	{
		super(id) ;
		this.name = name ;
		this.threads = new Vector<Long>() ;
		this.children = children ;
	}

	// for serialization
	@SuppressWarnings("unused")
	private Directory()
	{
		super(Persistent.INVALID_ID) ;
		System.out.println("building directory from nothing.") ;
		this.children = null ;
		this.name = null ;
		this.threads = null ;
	}

	/**
	 * Adds the directoryId to the vector of children of this directory.
	 * @param directoryId - the id of directory we need to add to the children of this directory
	 */
	public void addDirectory(final long directoryId)
	{
		this.lockWrite() ;
		try
		{
			this.children.add(directoryId) ;
		}
		finally
		{
			this.unlockWrite() ;
		}
	}

	/**
	 * Adds the Thread id to the correct vector of the Directory
	 * @param threadId - the id of thread we need to add
	 */
	public void addThread(final long threadId)
	{
		this.lockWrite() ;
		try
		{
			this.threads.add(threadId) ;
		}
		finally
		{
			this.unlockWrite() ;
		}
	}

	/**
	 * deletes the directory from the vector of children of this directory.
	 * @param directoryId the directory that we need to delete.
	 */
	public void deleteDirectory(final long directoryId)
	{
		this.lockWrite() ;
		try
		{
			this.children.remove(directoryId) ;
		}
		finally
		{
			this.unlockWrite() ;
		}
	}

	/**
	 * deletes the Thread from the correct vector of the directory
	 * @param threadId id of the thread to delete.
	 */
	public void deleteThread(final Long threadId)
	{
		this.lockWrite() ;
		try
		{
			this.threads.remove(threadId) ;
		}
		finally
		{
			this.unlockWrite() ;
		}
	}

	/**
	 * @return child directories of this directory.
	 */
	public Vector<Long> getChildren()
	{
		this.lockRead() ;
		try
		{
			return this.children ;
		}
		finally
		{
			this.unlockRead() ;
		}
	}

	/**
	 * @return the directory name
	 */
	public String getName()
	{
		this.lockRead() ;
		try
		{
			return this.name ;
		}
		finally
		{
			this.unlockRead() ;
		}
	}

	/**
	 * @return threads in this directory.
	 */
	public Vector<Long> getThreads()
	{
		this.lockRead() ;
		try
		{
			return this.threads ;
		}
		finally
		{
			this.unlockRead() ;
		}
	}

	/**
	 * set the directory name
	 * @param name - the new name to this directory
	 */
	public void setName(final String name)
	{
		this.lockWrite() ;
		try
		{
			this.name = name ;
		}
		finally
		{
			this.unlockWrite() ;
		}
	}

	/**
	 * function for debugging-return string with threads info
	 * @see persistence.Persistent#toString()
	 */
	@Override
	public String toString()
	{
		return super.toString() + " " + this.getName() ;
	}

	/**
	 * @param children set of children to set.
	 */
	protected void setChildren(final List<Long> children)
	{
		this.children = new Vector<Long>(children) ;
	}

	/**
	 * @param threads set of threads to set.
	 */
	protected void setThreads(final List<Long> threads)
	{
		this.threads = new Vector<Long>(threads) ;
	}

}
